package com.lcxw.hxzbapi.controller.membercontroller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lcxw.hxzbapi.entity.pojo.Attention;
import com.lcxw.hxzbapi.entity.pojo.Photo;
import com.lcxw.hxzbapi.entity.pojo.RealNameAuth;
import com.lcxw.hxzbapi.entity.pojo.ShortVideoComment;
import com.lcxw.hxzbapi.entity.pojo.YwpdConsume;
import com.lcxw.hxzbapi.entity.pojo.YwpdMember;
import com.lcxw.hxzbapi.entity.requestBean.PhotoDelReq;
import com.lcxw.hxzbapi.entity.requestBean.PhotoUploadReq;
import com.lcxw.hxzbapi.entity.requestBean.SubmitRealNameAuthReq;
import com.lcxw.hxzbapi.entity.response.Response;
import com.lcxw.hxzbapi.entity.response.RichLevelInfo;
import com.lcxw.hxzbapi.service.AttentionService;
import com.lcxw.hxzbapi.service.PhotoService;
import com.lcxw.hxzbapi.service.RealNameAuthService;
import com.lcxw.hxzbapi.service.YwpdConsumeService;
import com.lcxw.hxzbapi.service.YwpdMemberService;
import com.lcxw.hxzbcommon.common.AesCBCUtil;
import com.lcxw.hxzbcommon.common.DateUtils;
import com.lcxw.hxzbcommon.common.ObsUtil;
import com.lcxw.hxzbcommon.common.RedisUtils;
import com.lcxw.hxzbcommon.common.StringUtil;
import com.lcxw.hxzbcommon.entity.ErrorCode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.stereotype.Component;
import com.lcxw.hxzbapi.entity.pojo.Duanwei;
import com.lcxw.hxzbapi.entity.pojo.RichLevel;
import com.lcxw.hxzbapi.entity.pojo.VipLevel;
import com.lcxw.hxzbapi.service.DuanweiService;
import com.lcxw.hxzbapi.service.RichLevelService;
import com.lcxw.hxzbapi.service.VipLevelService;
import com.lcxw.hxzbapi.service.YwpdChargeDetailService;

@Component
@Slf4j
public class MemberRealization {

    @Resource
    DuanweiService duanweiService;

    @Resource
    VipLevelService vipLevelService;

    @Resource
    RichLevelService richLevelService;

    @Resource
    YwpdChargeDetailService chargeDetailService;

    @Resource
    RedisUtils redisUtils;

    @Resource
    YwpdMemberService ywpdMemberService;

    @Resource
    AttentionService attentionService;

    @Resource
    YwpdConsumeService consumeService;

    @Resource
    RealNameAuthService realNameAuthService;

    @Resource
    PhotoService photoService;

    private ObsUtil obsUtil = new ObsUtil();

    /**
     * 1、统计用户总共充值的虚拟货币总额
     */
    public int getChargeCoinTotal(long userId) {
        return chargeDetailService.selectCoinCount(userId);
    }

    /**
     * 2、遍历富豪等级，查询用户充值总额属于哪一个等级的富豪
     *
     * @param consumeTotal 充值总额， 虚拟货币
     * @return RichLevel
     */
    public RichLevel getRichLevel(int consumeTotal) throws Exception {
        List<RichLevel> richLevels = richLevelService.selectAll();
        for (RichLevel richlevel : richLevels
        ) {
            if (consumeTotal >= richlevel.getMin() && consumeTotal < richlevel.getMax()) {
                return richlevel;
            }
        }
        return richLevels.get(richLevels.size() - 1);
    }

    /**
     * 2.1 、获取用户的财富信息，包含财富等级权益等
     */
    public RichLevelInfo getRichLevelInfo(long userId) {
        Integer consumeTotal = getConsumeTotal(userId);
        RichLevel richLevel = null;
        try {
            richLevel = getRichLevel(consumeTotal);
        } catch (Exception e) {
            log.error("查询用户的财富等级失败");
        }
        RichLevelInfo data = new RichLevelInfo();
        data.setConsume(consumeTotal);
        data.setRichLevel(richLevel);
        data.setRichLevelRights(getRichLevelRights());
        return data;
    }

    /**
     * 2.2 、获取财富等级权益
     */
    private List getRichLevelRights() {

        List<LevelRight> levelRights = new ArrayList<>();

        LevelRight lv1 = new LevelRight();
        lv1.setLevelName("Lv.1");

        List<String> lv1Right = new ArrayList<>();
        lv1Right.add("直播间、聊天室进场特效");
        lv1Right.add("直播间、聊天室弹幕@功能");
        lv1.setRight(lv1Right);
        levelRights.add(lv1);

        LevelRight lv5 = new LevelRight();
        lv5.setLevelName("Lv.5");
        List<String> lv5Right = new ArrayList<>();
        lv5Right.add("背包游乐广场");
        lv5Right.add("幸运魔方和钻石魔方享受爆灯");
        lv5.setRight(lv5Right);
        levelRights.add(lv5);

        return levelRights;
    }

    /**
     * 3、遍历VIP等级，查询用户充值总额属于哪一个等级的vip
     *
     * @param chargeCoinTotal 充值总额， 虚拟货币
     * @return RichLevel
     */
    public VipLevel getVipLevel(int chargeCoinTotal) throws Exception {
        List<VipLevel> vipLevels = vipLevelService.selectAll();
        for (VipLevel vipLevel : vipLevels
        ) {
            if (chargeCoinTotal >= vipLevel.getMin() && chargeCoinTotal < vipLevel.getMax()) {
                return vipLevel;
            }
        }
        return vipLevels.get(vipLevels.size() - 1);
    }

    /**
     * 4、遍历段位等级，查询用户充值总额属于哪一个等级的段位
     *
     * @param chargeCoinTotal 充值总额， 虚拟货币
     * @return RichLevel
     */
    public Duanwei getDuanwei(int chargeCoinTotal) throws Exception {
        List<Duanwei> duanweis = duanweiService.selectAll();
        for (Duanwei duanwei : duanweis
        ) {
            if (chargeCoinTotal >= duanwei.getMin() && chargeCoinTotal < duanwei.getMax()) {
                return duanwei;
            }
        }
        return duanweis.get(duanweis.size() - 1);
    }

    /**
     * 5、获取用户的富豪等级、vip等级、段位等数据
     */
    public Map getLevels(long userId) throws Exception {
        int chargeCoinTotal = getChargeCoinTotal(userId);
        int consumeTotal = getConsumeTotal(userId);
        VipLevel vipLevel = getVipLevel(chargeCoinTotal);
        RichLevel richLevel = getRichLevel(consumeTotal);
        Duanwei duanwei = getDuanwei(chargeCoinTotal);

        Map<String, Object> data = new HashMap<>();
        data.put("richLevel", richLevel);
        data.put("vipLevel", vipLevel);
        data.put("duanwei", duanwei);
        return data;
    }

    /**
     * 6、生成用户的token并存储到redis中
     */
    public String genToken(long userId) throws Exception {
        //构造token 使用userId和时间戳，生成唯一token
        String tokenKey =
            userId + ":" + Calendar.getInstance().getTimeInMillis();
        String token = AesCBCUtil.getInstance().encrypt(tokenKey);

        //登录成功后，userId，和对应的token存到redis
        redisUtils.string_set("uid:" + userId + ":token", token);

        return token;
    }

    /**
     * 7、生成用户的token并存储到redis中
     */
    public String genToken(String userId) throws Exception {
        //构造token 使用userId和时间戳，生成唯一token
        String tokenKey =
            userId + ":" + Calendar.getInstance().getTimeInMillis();
        String token = AesCBCUtil.getInstance().encrypt(tokenKey);

        //登录成功后，userId，和对应的token存到redis
        redisUtils.string_set("uid:" + userId + ":token", token);

        return token;
    }

    /**
     * 8、获取用户的userId/头像/昵称的方法
     */
    public JSONObject getUserImgNickName(long userId) throws Exception {
        JSONObject jsonObject = new JSONObject();
        YwpdMember ywpdMember = ywpdMemberService.selectYwpdMemberByUserId(userId);
        if (null == ywpdMember) {
            return null;
        }
        jsonObject.put("userId", ywpdMember.getUserId());
        jsonObject.put("imgUrl", ywpdMember.getImgUrl());
        jsonObject.put("nickName", ywpdMember.getNickName());
        jsonObject.put("userName", ywpdMember.getUserName());
        jsonObject.put("age", ywpdMember.getAge());
        jsonObject.put("city", ywpdMember.getCity());
        jsonObject.put("sex", ywpdMember.getSex());
        jsonObject.put("occupation", ywpdMember.getOccupation());
        jsonObject.put("signature", ywpdMember.getSignature());

        Map levels = getLevels(userId);
        RichLevel richLevel = (RichLevel) levels.get("richLevel");
        VipLevel vipLevel = (VipLevel) levels.get("vipLevel");
        Duanwei duanwei = (Duanwei) levels.get("duanwei");

        jsonObject.put("richLevel", richLevel.getPicUrl());
        jsonObject.put("vipLevel", vipLevel.getPicUrl());
        jsonObject.put("duanwei", duanwei.getPicUrl());

        return jsonObject;

    }

    /**
     * 9、判断userId是否已关注attuId
     */
    public int isAtt(long userId, long attuId, String attype) {
        int isAtt = 0;
        Attention attention = attentionService
            .getAttentionByUserIdAndAttuId(userId, attuId, attype);
        if (null != attention) {
            isAtt = 1;
        }
        return isAtt;
    }

    /**
     * 9.1、获取用户的粉丝数量
     */
    public int getFansNum(long userId) {
        return attentionService.getFansNum(userId);
    }

    /**
     * 10、获取用户信息方法
     */
    public Map<String, Object> getUserInfo(long userId) throws Exception {

        Map<String, Object> data = new LinkedHashMap<>();

        YwpdMember ywpdMember = ywpdMemberService.selectYwpdMemberByUserId(userId);
        data.put("nickName", ywpdMember.getNickName());
        data.put("idCard", ywpdMember.getIdCard());
        data.put("realName", ywpdMember.getRealName());
        data.put("sex", ywpdMember.getSex());
        data.put("area", ywpdMember.getArea());
        data.put("province", ywpdMember.getProvince());
        data.put("city", ywpdMember.getCity());
        data.put("birthday", ywpdMember.getBirthday());
        data.put("curRoomNum", ywpdMember.getRoomId());
        data.put("bakPicUrl", ywpdMember.getBakPicUrl());
        data.put("imgUrl", ywpdMember.getImgUrl());
        data.put("vip", ywpdMember.getVip());
        data.put("vipExpire", ywpdMember.getVipExpire());
        data.put("spendCoin", ywpdMember.getSpendCoin());
        data.put("earnBean", ywpdMember.getEarnBean());
        data.put("freezeStatus", ywpdMember.getFreezeStatus());
        data.put("signature", ywpdMember.getSignature());
        data.put("qq", ywpdMember.getQq());
        data.put("address", ywpdMember.getAddress());
        data.put("daoju1", ywpdMember.getDaoju1());
        data.put("daoju1Expire", ywpdMember.getDaoju1Expire());
        data.put("age", ywpdMember.getAge());
        data.put("occupation", ywpdMember.getOccupation());
        data.put("school", ywpdMember.getSchool());
        data.put("roomId", ywpdMember.getRoomId());
        data.put("telephone", ywpdMember.getTelephone());

        return data;
    }

    /**
     * 11、获取朋友信息方法，主要提供给朋友圈模块使用
     */
    public Map<String, Object> getFriendInfo(long userId) throws Exception {

        Map<String, Object> data = new LinkedHashMap<>();

        YwpdMember ywpdMember = ywpdMemberService.selectYwpdMemberByUserId(userId);
        data.put("nickName", ywpdMember.getNickName());
        data.put("sex", ywpdMember.getSex());
        data.put("area", ywpdMember.getArea());
        data.put("province", ywpdMember.getProvince());
        data.put("city", ywpdMember.getCity());
        data.put("imgUrl", ywpdMember.getImgUrl());
        data.put("vip", ywpdMember.getVip());
        data.put("vipExpire", ywpdMember.getVipExpire());
        data.put("signature", ywpdMember.getSignature());
        data.put("age", ywpdMember.getAge());
        data.put("birthday", ywpdMember.getBirthday());
        data.put("occupation", ywpdMember.getOccupation());
        data.put("school", ywpdMember.getSchool());
        data.put("qq", ywpdMember.getQq());
        data.put("userName", ywpdMember.getUserName());

        String regTime = ywpdMember.getRegTime();
        String joinTime = DateUtils.getJoinTime(regTime, StringUtil.getDateTime());
        data.put("joinTime", joinTime);

        return data;
    }

    /**
     * 12、用户虚拟货币值变更方法
     */
    public void addCoin(int addCoin, long userId) {
        ywpdMemberService.updateCoinByUserId(addCoin, userId);
    }

    /**
     * 13、用户消费总额的添加
     */
    public void addConsume(long userId, int consume) {
        YwpdConsume ywpdConsume = consumeService.selectByUserId(userId);
        if (ywpdConsume == null) {
            YwpdConsume newConsume = new YwpdConsume();
            newConsume.setUserId(userId);
            newConsume.setConsume(consume);
            consumeService.insert(newConsume);
            return;
        }
        consumeService.updateConsumeByUserId(consume, userId);
    }

    /**
     * 14、查询用户消费总额
     */
    public Integer getConsumeTotal(long userId) {
        if (consumeService.selectByUserId(userId) == null) {
            return 0;
        }
        return consumeService.selectConsumeByUserId(userId);
    }

    /**
     * 15、获取一个用户的经纬度 坐标 ，用于计算两个位置的距离
     */
    public GlobalCoordinates getLngAndLat(long userId) {
        Map map = ywpdMemberService.selectLngAndLat(userId);
        if (null == map) {
            return new GlobalCoordinates(0, 0);
        }

        double longitude = Double.parseDouble(map.get("longitude").toString());
        double latitude = Double.parseDouble(map.get("latitude").toString());

        return new GlobalCoordinates(latitude, longitude);
    }

    /**
     * 16、计算两个经纬度坐标间的距离 返回值单位：米
     */
    public double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo) {

        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator()
            .calculateGeodeticCurve(Ellipsoid.Sphere, gpsFrom, gpsTo);

        return geoCurve.getEllipsoidalDistance();
    }

    /**
     * 17、计算两个用户之间的距离，单位：米
     */
    public double getDistance(long fromUserId, long toUserId) {
        GlobalCoordinates lngAndLat = getLngAndLat(fromUserId);
        GlobalCoordinates lngAndLat1 = getLngAndLat(toUserId);
        return getDistanceMeter(lngAndLat, lngAndLat1);
    }

    /**
     * 18、上传相册图片
     */
    Response uploadPhoto(PhotoUploadReq photoUploadReq) {
        long userId = Long.parseLong(photoUploadReq.getUserId());
        int photoNum = photoService.selectCountByUserId(userId);
        if (photoNum >= 16) {
            return Response.error(ErrorCode.INVALID_PARAM, "相册图片超过最大限制，最多上传16张图片");
        }
        String photoName = userId + "-" + (photoNum + 1);
        String imgName = "photo/" + photoName + "_photo.png";
        String imgOrigin = photoUploadReq.getImg();
        String photoUrl;
        try {
            photoUrl = obsUtil.uploadPic(imgName, imgOrigin);
        } catch (Exception e) {
            return Response.error(ErrorCode.EXTERNAL_ERROR, "上传图片到obs失败");
        }

        Photo photo = new Photo();
        photo.setUserId(userId);
        photo.setPhotoName(photoName);
        photo.setPhotoUrl(photoUrl);
        photoService.insert(photo);

        return Response.ok();
    }

    /**
     * 19、删除相册图片
     */
    Response deletePhoto(PhotoDelReq photoDelReq) {

        long userId = Long.parseLong(photoDelReq.getUserId());
        int photoNum = photoService.selectCountByUserId(userId);
        if (photoNum <= 1) {
            return Response.error(ErrorCode.INVALID_PARAM, "最后一张照片无法删除");
        }
        int id = photoDelReq.getId();
        photoService.deleteById(id);
        return Response.ok();
    }

    /**
     * 20、获取所有相册图片
     */
    public List<Photo> getAllPhotos(long userId) {
        return photoService.selectByUserId(userId);
    }

    /**
     * 21、实名认证方法
     *
     * @param requestBody
     * @return
     */
    public Response realNameAuth(SubmitRealNameAuthReq requestBody) {

        long userId = Long.parseLong(requestBody.getUserId());

        String realName = requestBody.getRealName();
        String idCardNum = requestBody.getIdCardNum();

        String idCardFront = requestBody.getIdCardFront();
        String picName_idCardFront = "idCard/" + userId + "_front.png";

        String idCardBack = requestBody.getIdCardBack();
        String picName_idCardBack = "idCard/" + userId + "_back.png";

        String idCardFrontUrl, idCardBackUrl;
        try {
            idCardFrontUrl = obsUtil.uploadPic(picName_idCardFront, idCardFront);
            idCardBackUrl = obsUtil.uploadPic(picName_idCardBack, idCardBack);
        } catch (Exception e) {
            return Response.error(ErrorCode.EXTERNAL_ERROR, "上传图片失败，请稍后再试");
        }

        RealNameAuth realNameAuth = realNameAuthService.selectByUserId(userId);

        if (realNameAuth == null) {
            realNameAuth = new RealNameAuth();
            realNameAuth.setUserId(userId);
            realNameAuth.setRealName(realName);
            realNameAuth.setIdCardNum(idCardNum);
            realNameAuth.setIdCardFront(idCardFrontUrl);
            realNameAuth.setIdCardBack(idCardBackUrl);
            realNameAuth.setAddTime(StringUtil.getDateTime());
            realNameAuth.setStatus("审核中");
            realNameAuthService.insert(realNameAuth);
            return Response.ok();
        } else {
            realNameAuth.setRealName(realName);
            realNameAuth.setIdCardNum(idCardNum);
            realNameAuth.setIdCardFront(idCardFrontUrl);
            realNameAuth.setIdCardBack(idCardBackUrl);
            realNameAuth.setStatus("审核中");
            realNameAuthService.update(realNameAuth);
        }

        return Response.ok();
    }

    public Response getRealNameAuthStatus(long userId) {
        YwpdMember ywpdMember;
        JSONObject data = new JSONObject();
        try {
            ywpdMember = ywpdMemberService.selectYwpdMemberByUserId(userId);
            if (ywpdMember.getRealNameAuth() == 1) {
                data.put("status", "认证通过");
                return Response.ok(data);
            }
        } catch (Exception e) {
            return Response.dbFail(log, "查询数据库失败");
        }

        RealNameAuth realNameAuth = realNameAuthService.selectByUserId(userId);
        if (realNameAuth == null) {
            data.put("status", "未认证");
            return Response.ok(data);
        } else if (realNameAuth.getStatus().equals("审核中")) {
            data.put("status", "审核中");
            return Response.ok(data);
        } else if (realNameAuth.getStatus().equals("认证未通过")) {
            data.put("status", "认证未通过");
            data.put("reason", realNameAuth.getReason());
            return Response.ok(data);
        }

        return Response.error(ErrorCode.INTERNAL_ERROR, "查询失败，请稍后再试");

    }

    public Response getRealNameAuthList(String status, int pageNum, int pageSize) {
        if (StringUtil.isEmpty(status)) {
            status = null;
        }
        if (pageSize == 0) {
            pageSize = 10;
        }
        IPage<RealNameAuth> realNameAuthIPage = realNameAuthService
            .selectListByStatus(status, pageNum, pageSize);
        JSONObject data = new JSONObject();
        data.put("total", realNameAuthIPage.getTotal());
        data.put("realNameAuthList", realNameAuthIPage.getRecords());

        return Response.ok(data);
    }

    public Response dealRealNameAuth(int id, String status, String reason, String adminName)
        throws Exception {
        RealNameAuth realNameAuth = realNameAuthService.selectById(id);
        realNameAuth.setStatus(status);
        realNameAuth.setReason(reason);
        realNameAuth.setCheckTime(StringUtil.getDateTime());
        realNameAuth.setCheckUser(adminName);
        realNameAuthService.update(realNameAuth);

        if (status.equals("认证通过")) {
            Long userId = realNameAuth.getUserId();
            YwpdMember ywpdMember = ywpdMemberService.selectYwpdMemberByUserId(userId);
            ywpdMember.setRealNameAuth(1);
            ywpdMember.setRealName(realNameAuth.getRealName());
            ywpdMemberService.updateYwpdMember(ywpdMember);
        }

        return Response.ok();
    }

    @Data
    static class LevelRight {

        String levelName;

        List<String> right;
    }

}
